package com.sugo.seckill.order.service;

import com.sugo.seckill.http.HttpResult;
import com.sugo.seckill.page.PageResult;
import com.sugo.seckill.pojo.FrontUser;
import com.sugo.seckill.pojo.TbPayLog;
import com.sugo.seckill.pojo.TbSeckillOrder;
import org.springframework.transaction.annotation.Transactional;

/**
 * 服务层接口
 *
 * @author Administrator
 */
public interface SeckillOrderService {

    /**
     * 返回分页列表
     */
    PageResult findPage(int pageNum, int pageSize);


    /**
     * 根据ID获取实体
     */
    TbSeckillOrder findOne(Long id);


    /**
     * 方式1-1： 普通秒杀下单 会出现库存超卖现象
     */
    HttpResult startSubmitOrder(Long seckillId, String userId);

    /**
     * 方式1-2： 普通秒杀下单 会出现库存超卖现象（多线程的方式）
     * @param seckillId 商品ID
     * @param userId    用户ID
     */
    HttpResult startSubmitOrderMultiThread(Long seckillId, String userId);

    /**
     * 2-1 使用程序锁实现库存超卖控制
     *
     * @author hubin
     * @date 2020/9/5 20:48
     */
    HttpResult startSubmitOrderByReentrantLock(Long seckillId, String userId);


    /**
     *  3-1 使用aop锁实现库存超卖控制
     * @author hubin
     * @date 2020/9/5 20:48
     */
    HttpResult startSubmitOrderByAOPLock(Long seckillId, String userId);

    /**
     *  4-1 使用队列的方式实现库存控制
     * @author hubin
     * @date 2020/9/5 20:48
     */
    HttpResult startSubmitOrderByBlockingQueue(Long seckillId, String userId);

    /**
     * 4-2 使用队列+多线程的方式实现库存控制
     */
    HttpResult startSubmitOrderByBlockingQueueMultiThread(Long seckillId, String userId);


    /**
     * 5-1 第一种-使用数据库悲观锁控制库存
     * @author hubin
     * @date 2020/9/12 20:42
     */
    HttpResult startSubmitOrderBySQLPessimismLock(Long seckillId, String userId);

    /**
     * 5-2 第二种-使用数据库悲观锁控制库存
     * @author hubin
     * @date 2020/9/12 20:42
     */
    HttpResult startSubmitOrderBySQLPessimismLock2(Long seckillId, String userId);

    /**
     * 5-3 使用数据库乐观锁锁控制库存
     * @author hubin
     * @date 2020/9/12 21:23
     */
    HttpResult startSubmitOrderBySQLOptimismLock(Long seckillId, String userId);


    /**
     * 6-1 redis分布式锁的方式进行上锁
     *
     * @author hubin
     * @date 2020/9/12 22:20
     */
    HttpResult startSubmitOrderByRedissonLock(Long seckillId, String userId);


    @Transactional
    HttpResult startSubmitOrderByAOPRedissonLock(Long seckillId, String userId);

    @Transactional
    HttpResult startSubmitOrderByRedisIncrement(Long seckillId, String userId);

    /**
     * 7-1 使用redisson分布式锁方案控制库存，实现下单
     * @author hubin
     * @date 2020/9/5 20:48
     */
    HttpResult startSubmitOrderByZookeeperLock(Long seckillId, String userId);


    @Transactional
    HttpResult startSubmitOrderByRcoketMQ(Long seckillId, String userId);

    /**
     * 下单-添加订单
     * @param userId 用户ID
     * @param seckillId 商品ID
     */
    void placeOrder(long seckillId, String userId);

    /**
     * 修改订单状态
     * @param out_trade_no 订单号
     * @param transaction_id 流水号
     */
    void updateOrderStatus(String out_trade_no, String transaction_id);


    TbPayLog searchPayLogFromRedis(String userId);

    /**
     *  从redis中查询用户信息
     * @author hubin
     * @date 2020/6/10 10:47
     */
    FrontUser getUserInfoFromRedis(String token);

    HttpResult getOrderMoney(Long orderId);

    TbSeckillOrder findOrderById(Long orderId);

    void getSeckillGoods(Long seckillId);
}
